﻿using System;
using System.Collections.Generic;
using System.Linq;
using Hammock;

namespace OpenNOSClient
{
    public abstract class OpenNOSRestClientSync : OpenNOSRestClientAsync
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="OpenNOSRestClientSync"/> class.
        /// </summary>
        /// <param name="key">The key.</param>
        protected OpenNOSRestClientSync(string key)
            : base(key)
        {
        }

        /// <summary>
        /// Gets the latest articles.
        /// </summary>
        /// <param name="category">The category.</param>
        /// <returns>Articles</returns>
        public IEnumerable<Article> GetLatestArticles(OpenNOSCategory category)
        {
            string path = GeneratePath(OpenNOSRequestTypes.LatestArticles, category);
            var openNOSResponse = Request<OpenNOSResponse>(path);
            return openNOSResponse.LatestArticles.FirstOrDefault();
        }

        /// <summary>
        /// Gets the latest audio.
        /// </summary>
        /// <param name="category">The category.</param>
        /// <returns>Audio Items</returns>
        public IEnumerable<Audio> GetLatestAudio(OpenNOSCategory category)
        {
            string path = GeneratePath(OpenNOSRequestTypes.LatestAudio, category);
            var openNOSResponse = Request<OpenNOSResponse>(path);
            return openNOSResponse.LatestAudio.FirstOrDefault();
        }

        /// <summary>
        /// Gets the latest video.
        /// </summary>
        /// <param name="category">The category.</param>
        /// <returns>Video Items</returns>
        public IEnumerable<Video> GetLatestVideo(OpenNOSCategory category)
        {
            string path = GeneratePath(OpenNOSRequestTypes.LatestVideo, category);
            var openNOSResponse = Request<OpenNOSResponse>(path);
            return openNOSResponse.LatestVideo.FirstOrDefault();
        }

        /// <summary>
        /// Searches the content.
        /// </summary>
        /// <param name="query">The query.</param>
        /// <returns>SearchResult</returns>
        public SearchResult SearchContent(string query)
        {
            string path = GenerateQueryPath(query);
            var openNOSResponse = Request<OpenNOSResponse>(path);
            return openNOSResponse.SearchResults.FirstOrDefault();
        }

        public IEnumerable<GuideResult> GetRadioGuide(DateTime? startDate, DateTime? endDate, string channel)
        {
            return GetGuide(OpenNOSRequestTypes.RadioGuide, startDate, endDate, channel);
        }

        public IEnumerable<GuideResult> GetTVGuide(DateTime? startDate, DateTime? endDate, string channel)
        {
            return GetGuide(OpenNOSRequestTypes.TVGuide, startDate, endDate, channel);
        }

        public IEnumerable<GuideResult> GetGuide(string guide, DateTime? startDate, DateTime? endDate, string channel)
        {
            if (startDate == null && endDate != null)
            {
                throw new ArgumentException("StartDate is not filled in");
            }

            if (startDate != null && endDate == null)
            {
                throw new ArgumentException("EndDate is not filled in");
            }

            string path = GenerateGuidePath(guide, startDate, endDate, channel);

            var openNOSResponse = Request<OpenNOSResponse>(path);
            return openNOSResponse.GuideResults.SingleOrDefault();
        }

        /// <summary>
        /// Send a REST Request to the specified path.
        /// </summary>
        /// <param name="path">The path.</param>
        /// <returns>OpenNOSResponse</returns>
        private T Request<T>(string path)
        {
            var request = new RestRequest
            {
                Path = path
            };

            return Client.Request<T>(request).ContentEntity;
        }
    }
}
